package com.linsy.product.redis.mq.util;

import cn.hutool.core.text.CharSequenceUtil;
import com.linsy.product.redis.mq.entity.MqDataVO;
import com.linsy.product.redis.mq.entity.MqTaskKeyConstant;
import com.linsy.product.redis.mq.entity.PutMsgDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalTime;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {

    @Autowired
    @Qualifier("cacheRedisTemplate")
    private RedisTemplate<String, Object> cacheRedisTemplate;

    /**
     * 如果在time时间内取到size个数据，立马返回。否则超时后，取到多少返回多少。
     *
     * @param key 消息主题
     * @param size 一次取多少个回去处理消费
     * @param time 时长（秒），需小于60秒
     * @return 返回数据
     */
    public List<MqDataVO> pullTask(String key, Long size, Long time) throws Exception {
        if (CharSequenceUtil.isBlank(key) || time >= 60 || size <= 0) {
            throw new Exception("参数错误");
        }
        List<MqDataVO> value = new LinkedList<>();
        long leftTime = time;
        for (int i = 0; i < size; i++) {
            LocalTime beforeTime = LocalTime.now();
            Object items = lPopBlock(MqTaskKeyConstant.MQ_KEY + key, leftTime);
            if (items != null) {
                value.add(MqDataVO.objectToVO(items));
            }
            // 算时差
            Duration between = Duration.between(beforeTime, LocalTime.now());
            long l = between.getSeconds();
            leftTime -= l;
            // 看是否超时
            if (leftTime <= 0) {
                break;
            }
        }

        return value;
    }


    public Object lPopBlock(String key, Long time) {
        return cacheRedisTemplate.opsForList().leftPop(key, time, TimeUnit.SECONDS);
    }

    public boolean rPush(PutMsgDTO dto) {
        return cacheRedisTemplate.opsForList().rightPushAll(dto.getKey(), dto.getValue()) != null;
    }

}
